package com.lyeducation.controllers.system;

import com.aliyuncs.exceptions.ClientException;
import com.lyeducation.controllers.dto.EmailDto;
import com.lyeducation.controllers.dto.system.InsertSysUserDto;
import com.lyeducation.core.base.LOGINREGISTER;
import com.lyeducation.core.base.LOGINSAVEUSERTYPE;
import com.lyeducation.core.base.SysConstants;
import com.lyeducation.core.system.SysUserService;
import com.lyeducation.entities.system.SysUserEntity;
import com.lyeducation.repository.system.SysUserRepository;
import com.lyeducation.security.config.SecurityPrincipalContext;
import com.lyeducation.util.CodeUtil;
import com.lyeducation.util.StringUtils;
import com.lyeducation.util.aLiYunSms.ALiYunSmsUtil;
import com.lyeducation.util.controllerUtil.ControllerUtil;
import com.lyeducation.util.controllerUtil.JsonConstans;
import com.lyeducation.util.controllerUtil.JsonResult;
import com.lyeducation.util.mail.MailRecipient;
import com.lyeducation.util.mail.MailSendUtil;
import com.lyeducation.util.mail.TemplateMessage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.social.connect.web.ProviderSignInUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileNotFoundException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Api(
        value = "用户模块相关部分用户接口不在此，如登录注册接口",
        tags = {"用户,{mId}菜单id"},
        description = "用户登录注册相关操作接口"
)
@RestController
@RequestMapping("sysUser")
public class SysUserController {
  @Autowired private SysUserService sysUserService;
  @Autowired
  private MailSendUtil mailSendUtil;
  @Autowired
  private ALiYunSmsUtil aLiYunSmsUtil;
  @Autowired
  private RedisTemplate redisTemplate;
  @Autowired
  private SysUserRepository sysUserRepository;

  @Autowired
  private ProviderSignInUtils providerSignInUtils;

  public JsonResult getSysUserTablet() {
    return JsonResult.putFail("非管理员无权限操作!");
  }

  /**
   * 后台管理用户列表
   *
   * @param pageNo
   * @param pageSize
   * @return
   */
  @ApiOperation(value = "后台管理用户列表")
  @GetMapping("getSysUserTable/{pageNo}/{pageSize}")
  public JsonResult getSysUserTable(@PathVariable int pageNo, @PathVariable int pageSize) {
    if (SecurityPrincipalContext.checkHasAdminOrGeneralAdminRole()) {
      return sysUserService.getSysUserTable(pageNo, pageSize);
    } else {
      return JsonResult.putFail("非管理员无权限操作!");
    }
  }

  /**
   * 禁用用户
   *
   * @return
   */
  @ApiOperation(value = "禁用用户", notes = "enabledSysUser/{true}/{userId}")
  @GetMapping("enabledSysUser/{enabled}/{userId}")
  public JsonResult enabledSysUser(@PathVariable boolean enabled, @PathVariable String userId) {
    if (SecurityPrincipalContext.checkHasAdminOrGeneralAdminRole()) {
      return sysUserService.enabledSysUser(enabled, userId);
    } else {
      return JsonResult.putFail("非管理员无权限操作!");
    }
  }

  @ApiOperation(value = "软删除用户", notes = "updIsDeleteSysUser/{true}/{userId}")
  @GetMapping("updIsDeleteSysUser/{isDelete}/{userId}")
  public JsonResult updIsDeleteSysUseupdIsDeleteSysUserr(
          @PathVariable boolean isDelete, @PathVariable String userId) {
    if (SecurityPrincipalContext.checkHasAdminOrGeneralAdminRole()) {
      return sysUserService.updIsDeleteSysUser(isDelete, userId);
    } else {
      return JsonResult.putFail("非管理员无权限操作!");
    }
  }

  @ApiOperation(value = "获取用户信息")
  @GetMapping("getUserMsg")
  public JsonResult getUserMsg() {
    return JsonResult.putSuccess(
            sysUserService.findById(SecurityPrincipalContext.getUserDetailsImpl().getId()));
  }

  // insertUserType 0 邮箱注册 1 手机注册 不填/其他普通注册
  @ApiOperation(value = "添加更新用户", notes = "添加更新用户")
  @PostMapping("addUpdSysUser")
  public JsonResult addUpdSysUser(@RequestBody InsertSysUserDto insertSysUserDto)
          throws FileNotFoundException, InterruptedException, ClientException, ExecutionException {
    //    insertSysUserDto.setName(insertSysUserDto.getName().trim());
    //    insertSysUserDto.setNickName(insertSysUserDto.getNickName().trim());
    //    insertSysUserDto.setIdentityCard(insertSysUserDto.getIdentityCard().trim());
    Integer insertUserType = insertSysUserDto.getInsertUserType();
    boolean mailBlank = StringUtils.isBlank(insertSysUserDto.getEmail());
    boolean mobileBlank = StringUtils.isBlank(insertSysUserDto.getMobile());
    JsonResult jsonResult = null;
    if (StringUtils.isBlank(insertSysUserDto.getId())) {
      if (insertUserType != null) {
        Object code = null;
        if (insertUserType == LOGINSAVEUSERTYPE.LOGIN_SAVE_USER_TYPE_BY_EMAIL.ordinal()) {
          if (mailBlank) {
            jsonResult = JsonResult.putFail("邮箱不能为空");
          }
          Object codeTimeOutObj =
                  redisTemplate
                          .opsForHash()
                          .get(
                                  SysConstants.EMAIL_REGISTER_CODE_HASH.getValue(),
                                  insertSysUserDto.getEmail());
          if (codeTimeOutObj == null) {
            return JsonResult.putFail("未查询到该邮箱验证码");
          }
          Object[] codeTimeOutArray = (Object[]) codeTimeOutObj;
          code = codeTimeOutArray[0].toString();
          long timeOut = (long) codeTimeOutArray[1];
          //          if (code == null) {
          //            return JsonResult.putFail("手机验证码失效");
          //          }
          if (timeOut < System.currentTimeMillis()) {
            redisTemplate
                    .opsForHash()
                    .delete(
                            SysConstants.EMAIL_REGISTER_CODE_HASH.getValue(), insertSysUserDto.getMobile());
            throw new RuntimeException("邮箱验证码过期");
          }
          //          if (code == null) {
          //            return JsonResult.putFail("邮箱验证码失效");
          //          }
          if (!StringUtils.equals(code.toString(), insertSysUserDto.getCode())) {
            return JsonResult.putFail("校验错误，请输入正确验证码");
          }
        } else if (insertUserType == LOGINSAVEUSERTYPE.LOGIN_SAVE_USER_TYPE_BY_MOBILE.ordinal()) {
          if (mobileBlank) {
            jsonResult = JsonResult.putFail("手机号不能为空");
          }
          Object codeTimeOutObj =
                  redisTemplate
                          .opsForHash()
                          .get(
                                  SysConstants.MOBILE_REGISTER_CODE_HASH.getValue(),
                                  insertSysUserDto.getMobile());
          if (codeTimeOutObj == null) {
            return JsonResult.putFail("未查询到该手机验证码");
          }
          Object[] codeTimeOutArray = (Object[]) codeTimeOutObj;
          code = codeTimeOutArray[0].toString();
          long timeOut = (long) codeTimeOutArray[1];
          //          if (code == null) {
          //            return JsonResult.putFail("手机验证码失效");
          //          }
          if (timeOut < System.currentTimeMillis()) {
            redisTemplate
                    .opsForHash()
                    .delete(
                            SysConstants.MOBILE_REGISTER_CODE_HASH.getValue(),
                            insertSysUserDto.getMobile());
            throw new RuntimeException("手机验证码过期");
          }
          if (!StringUtils.equals(code.toString(), insertSysUserDto.getCode())) {
            return JsonResult.putFail("校验错误，请输入正确验证码");
          }
        } else {
          jsonResult = insertSysUserDto.checkName("账号名");
        }
      } else {
        jsonResult = insertSysUserDto.checkName("账号名");
      }
    } else {
      if (SecurityPrincipalContext.getUserDetailsImpl() != null) {
        if (!StringUtils.equals(
                SecurityPrincipalContext.getUserDetailsImpl().getId(), insertSysUserDto.getId())) {
          jsonResult = JsonResult.putFail(JsonConstans.ERR_NOTVALID_AUTH);
        }
      } else {
        jsonResult = JsonResult.putFail(JsonConstans.ERR_NOTVALID_AUTH);
      }
    }
    if (jsonResult != null) {
      return jsonResult;
    }
    jsonResult = insertSysUserDto.checkName("密码", insertSysUserDto.getPassword(), 12);
    if (jsonResult != null) {
      return jsonResult;
    }

    if (StringUtils.isBlank(insertSysUserDto.getNickName())) {
      insertSysUserDto.setNickName("领英用户" + CodeUtil.generateUniqueCode());
    }
    //    jsonResult = insertSysUserDto.checkName("昵称", insertSysUserDto.getNickName(), 255);
    //    if (jsonResult != null) {
    //      return jsonResult;
    //    }

    if (!mailBlank) {
      if (!ControllerUtil.isMailNo(insertSysUserDto.getEmail())) {
        return JsonResult.putFail("邮箱格式错误");
      }
    }
    if (!mobileBlank) {
      if (!ControllerUtil.isMobileNO(insertSysUserDto.getMobile())) {
        return JsonResult.putFail("手机号格式错误");
      }
    }
    if (StringUtils.isNotBlank(insertSysUserDto.getIdentityCard())) {

      if (!ControllerUtil.isValidIdNo(insertSysUserDto.getIdentityCard())) {
        return JsonResult.putFail("身份证格式错误");
      }
    }

    if (StringUtils.isNotBlank(insertSysUserDto.getPhone())) {
      if (!ControllerUtil.isPhoneNo(insertSysUserDto.getPhone())) {
        return JsonResult.putFail("电话号码格式错误");
      }
    }
    if (insertSysUserDto.getBirthTime() != null) {
      if (insertSysUserDto.getBirthTime().after(new Timestamp(System.currentTimeMillis()))) {
        return JsonResult.putFail("出生日期输入非法");
      }
    }

    jsonResult = sysUserService.saveOrUpdate(insertSysUserDto, true);

    return jsonResult;
  }

  @ApiOperation(value = "后台修改用户基本信息", notes = "后台修改用户基本信息")
  @PostMapping("updUserByAdmin")
  public JsonResult updUserByAdmin(@RequestBody InsertSysUserDto insertSysUserDto)
          throws FileNotFoundException, InterruptedException, ClientException, ExecutionException {
    if (!SecurityPrincipalContext.checkHasAdminOrGeneralAdminRole()) {
      return JsonResult.putFail("无管理员权限无法修改用户基本信息");
    }
    if (StringUtils.trimToNull(insertSysUserDto.getId()) == null) {
      return JsonResult.putFail("id不能为空");
    }

    Integer insertUserType = insertSysUserDto.getInsertUserType();
    boolean mailBlank = StringUtils.isBlank(insertSysUserDto.getEmail());
    boolean mobileBlank = StringUtils.isBlank(insertSysUserDto.getMobile());
    JsonResult jsonResult = null;
    if (StringUtils.isBlank(insertSysUserDto.getId())) {
      if (insertUserType != null) {
        //        Object code = null;
        if (insertUserType == LOGINSAVEUSERTYPE.LOGIN_SAVE_USER_TYPE_BY_EMAIL.ordinal()) {
          if (mailBlank) {
            jsonResult = JsonResult.putFail("邮箱不能为空");
          }
          //          Object codeTimeOutObj =
          //                  redisTemplate
          //                          .opsForHash()
          //                          .get(
          //                                  SysConstants.EMAIL_REGISTER_CODE_HASH.getValue(),
          //                                  insertSysUserDto.getEmail());
          //          if (codeTimeOutObj == null) {
          //            return JsonResult.putFail("未查询到该邮箱验证码");
          //          }
          //          Object[] codeTimeOutArray = (Object[]) codeTimeOutObj;
          //          code = codeTimeOutArray[0].toString();
          //          long timeOut = (long) codeTimeOutArray[1];
          //          if (code == null) {
          //            return JsonResult.putFail("手机验证码失效");
          //          }
          //          if (timeOut < System.currentTimeMillis()) {
          //
          // redisTemplate.opsForHash().delete(SysConstants.EMAIL_REGISTER_CODE_HASH.getValue(),
          // insertSysUserDto.getMobile());
          //            throw new RuntimeException("邮箱验证码过期");
          //          }
          //          if (code == null) {
          //            return JsonResult.putFail("邮箱验证码失效");
          //          }
          //          if (!StringUtils.equals(code.toString(), insertSysUserDto.getCode())) {
          //            return JsonResult.putFail("校验错误，请输入正确验证码");
          //          }
        } else if (insertUserType == LOGINSAVEUSERTYPE.LOGIN_SAVE_USER_TYPE_BY_MOBILE.ordinal()) {
          if (mobileBlank) {
            jsonResult = JsonResult.putFail("手机号不能为空");
          }
          //          Object codeTimeOutObj =
          //                  redisTemplate
          //                          .opsForHash()
          //                          .get(
          //                                  SysConstants.MOBILE_REGISTER_CODE_HASH.getValue(),
          //                                  insertSysUserDto.getMobile());
          //          if (codeTimeOutObj == null) {
          //            return JsonResult.putFail("未查询到该手机验证码");
          //          }
          //          Object[] codeTimeOutArray = (Object[]) codeTimeOutObj;
          //          code = codeTimeOutArray[0].toString();
          //          long timeOut = (long) codeTimeOutArray[1];
          ////          if (code == null) {
          ////            return JsonResult.putFail("手机验证码失效");
          ////          }
          //          if (timeOut < System.currentTimeMillis()) {
          //
          // redisTemplate.opsForHash().delete(SysConstants.MOBILE_REGISTER_CODE_HASH.getValue(),
          // insertSysUserDto.getMobile());
          //            throw new RuntimeException("手机验证码过期");
          //          }
          //          if (!StringUtils.equals(code.toString(), insertSysUserDto.getCode())) {
          //            return JsonResult.putFail("校验错误，请输入正确验证码");
          //          }
        } else {
          jsonResult = insertSysUserDto.checkName("账号名");
        }
      } else {
        jsonResult = insertSysUserDto.checkName("账号名");
      }
    } else {
      if (SecurityPrincipalContext.getUserDetailsImpl() != null) {
        if (!StringUtils.equals(
                SecurityPrincipalContext.getUserDetailsImpl().getId(), insertSysUserDto.getId())) {
          jsonResult = JsonResult.putFail(JsonConstans.ERR_NOTVALID_AUTH);
        }
      } else {
        jsonResult = JsonResult.putFail(JsonConstans.ERR_NOTVALID_AUTH);
      }
    }
    if (jsonResult != null) {
      return jsonResult;
    }
    jsonResult = insertSysUserDto.checkName("密码", insertSysUserDto.getPassword(), 12);
    if (jsonResult != null) {
      return jsonResult;
    }

    if (StringUtils.isBlank(insertSysUserDto.getNickName())) {
      insertSysUserDto.setNickName("领英用户" + CodeUtil.generateUniqueCode());
    }
    //    jsonResult = insertSysUserDto.checkName("昵称", insertSysUserDto.getNickName(), 255);
    //    if (jsonResult != null) {
    //      return jsonResult;
    //    }

    if (!mailBlank) {
      if (!ControllerUtil.isMailNo(insertSysUserDto.getEmail())) {
        return JsonResult.putFail("邮箱格式错误");
      }
    }
    if (!mobileBlank) {
      if (!ControllerUtil.isMobileNO(insertSysUserDto.getMobile())) {
        return JsonResult.putFail("手机号格式错误");
      }
    }
    if (StringUtils.isNotBlank(insertSysUserDto.getIdentityCard())) {

      if (!ControllerUtil.isValidIdNo(insertSysUserDto.getIdentityCard())) {
        return JsonResult.putFail("身份证格式错误");
      }
    }

    if (StringUtils.isNotBlank(insertSysUserDto.getPhone())) {
      if (!ControllerUtil.isPhoneNo(insertSysUserDto.getPhone())) {
        return JsonResult.putFail("电话号码格式错误");
      }
    }
    if (insertSysUserDto.getBirthTime() != null) {
      if (insertSysUserDto.getBirthTime().after(new Timestamp(System.currentTimeMillis()))) {
        return JsonResult.putFail("出生日期输入非法");
      }
    }

    jsonResult = sysUserService.saveOrUpdate(insertSysUserDto, false);

    return jsonResult;
  }

  @ApiOperation(value = "邮箱激活用户", notes = "邮箱激活用户")
  @GetMapping("activeUserByEmailUrl/{uId}")
  public JsonResult activeUser(@PathVariable String uId) {
    return sysUserService.activeUser(uId, LOGINREGISTER.TYPE_LOGIN_MAIL.ordinal());
  }

  @GetMapping("sendRegisterCodeToMobile/{mobileNumber}")
  public JsonResult sendUserByMobileCode(@PathVariable String mobileNumber)
          throws ClientException, ExecutionException, InterruptedException {
    Future<String> task =
            aLiYunSmsUtil.sendCodeSms(mobileNumber, LOGINREGISTER.TYPE_REGISTER_MOBILE.ordinal());
    while (true) {
      if (task.isDone()) {
        String responseCode = task.get();
        if (StringUtils.equals(responseCode, "OK")) {
          return JsonResult.putSuccess();
        }
        return JsonResult.putFail("短信发送超过限制");
      }
    }
  }

  @PostMapping("sendRegisterCodeToEmail")
  public JsonResult sendRegisterCodeToEmail(@RequestBody EmailDto email)
          throws FileNotFoundException {
    String param = CodeUtil.generateActiveCode();
    //    File[] files = new File[2];
    //    files[0] = new File("C:\\Users\\WSF\\Desktop\\timg.jpg");
    //    files[1] = new File("C:\\Users\\WSF\\Desktop\\宽带.txt");
    File contentImage =
            ResourceUtils.getFile("classpath:templates/user/registration/img/lyEducation.png");
    TemplateMessage templateMessage = new TemplateMessage();
    templateMessage.setActiveMsg(param);
    String content = mailSendUtil.readTemplate(templateMessage, "user/registration/activeUrl.ftl");

    List<MailRecipient> infos = new ArrayList<>();
    //    subject不可随意填写会报554 垃圾邮件
    MailRecipient mailRecipient =
            MailRecipient.getMailInfo(
                    email.getEmail(), null, null, "领英教育账号激活", content, contentImage, "a", null);
    Future<Boolean> task2 = mailSendUtil.sendMail(mailRecipient);

    Object[] o = new Object[2];
    o[0] = param;
    o[1] = 90000 + System.currentTimeMillis();
    //    没有这行无法发送邮件
    while (true) {
      if (task2.isDone()) {
        redisTemplate
                .opsForHash()
                .put(SysConstants.EMAIL_REGISTER_CODE_HASH.getValue(), email.getEmail(), o);
        //        redisTemplate.expire(
        //                SysConstants.MOBILE_REGISTER_CODE_HASH.getValue(), 90, TimeUnit.SECONDS);
        break;
      }
    }
    return JsonResult.putSuccess();
  }

  @ApiOperation(value = "手机激活用户", notes = "手机激活用户")
  @GetMapping("activeUserByMobileCode/{mobile}/{activeCode}")
  public JsonResult activeUserByMobileCode(
          @PathVariable String mobile, @PathVariable String activeCode) {
    Object code =
            redisTemplate.opsForHash().get(SysConstants.MOBILE_REGISTER_CODE_HASH.getValue(), mobile);
    if (code == null) {
      return JsonResult.putFail("手机验证码失效");
    }
    if (!StringUtils.equals(code.toString(), activeCode)) {
      return JsonResult.putFail("校验错误，请输入正确验证码");
    }
    return sysUserService.activeUser(mobile, LOGINREGISTER.TYPE_REGISTER_MOBILE.ordinal());
  }

  // 邮箱登录
  //  @GetMapping("sendLoginCodeByEmail")
  public JsonResult sendLoginCodeByEmail(String email) throws FileNotFoundException {
    if (!ControllerUtil.isMailNo(email)) {
      return JsonResult.putFail("邮箱格式错误");
    }
    SysUserEntity sysUserEntity =
            sysUserRepository.getUserByIdCodeEmailMobile(SysConstants.EMAIL.toString(), email);
    if (sysUserEntity == null) {
      return JsonResult.putFail("无法发送验证码至" + email + ",请确认邮箱是否填写正确");
    }
    File contentImage =
            ResourceUtils.getFile("classpath:templates/user/registration/img/lyEducation.png");
    TemplateMessage templateMessage = new TemplateMessage();
    String activeCode = CodeUtil.generateActiveCode();
    templateMessage.setActiveMsg(activeCode);
    String content = mailSendUtil.readTemplate(templateMessage, "user/login/activeCode.ftl");

    List<MailRecipient> infos = new ArrayList<>();
    //    subject不可随意填写会报554 垃圾邮件
    MailRecipient mailRecipient =
            MailRecipient.getMailInfo(
                    sysUserEntity.getEmail(), null, null, "领英教育验证码", content, contentImage, "a", null);
    Future<Boolean> task2 = mailSendUtil.sendMail(mailRecipient);

    redisTemplate
            .opsForHash()
            .put(SysConstants.EMAIL_ACTIVE_CODE_HASH.getValue(), sysUserEntity.getEmail(), activeCode);
    redisTemplate.expire(SysConstants.EMAIL_ACTIVE_CODE_HASH.getValue(), 90, TimeUnit.SECONDS);
    return JsonResult.putSuccess();
  }

  // 手机验证码登录
  @ApiOperation(value = "手机验证码登录", notes = "手机验证码登录")
  @GetMapping("sendLoginCodeByMobile/{mobile}")
  public JsonResult sendLoginCodeByMobile(@PathVariable String mobile)
          throws ClientException, ExecutionException, InterruptedException {
    if (!ControllerUtil.isMobileNO(mobile)) {
      return JsonResult.putFail("手机号格式错误");
    }
    SysUserEntity sysUserEntity =
            sysUserRepository.getUserByIdCodeEmailMobile(SysConstants.MOBILE.toString(), mobile);
    if (sysUserEntity == null) {
      return JsonResult.putFail("无法发送验证码至" + mobile + ",请确认手机号是否填写正确");
    }
    Future<String> task =
            aLiYunSmsUtil.sendCodeSms(mobile, LOGINREGISTER.TYPE_LOGIN_MAIL.ordinal());
    while (true) {
      if (task.isDone()) {
        String responseCode = task.get();
        if (StringUtils.equals(responseCode, "OK")) {
          return JsonResult.putSuccess();
        }
        return JsonResult.putFail("短信发送超过限制");
      }
    }
  }
  //
  //  /**
  //   * 获取第三方用户信息
  //   *
  //   * @param request
  //   * @return
  //   */
  //  @GetMapping("/social/info")
  //  public @ResponseBody
  //  SocialUserInfo getSocialUserInfo(HttpServletRequest request) {
  //    SocialUserInfo userInfo = new SocialUserInfo();
  //    Connection<?> connection =
  //            providerSignInUtils.getConnectionFromSession(new ServletWebRequest(request));
  //    userInfo.setProviderId(connection.getKey().getProviderId());
  //    userInfo.setProviderUserId(connection.getKey().getProviderUserId());
  //    userInfo.setNickname(connection.getDisplayName());
  //    userInfo.setHeadImg(connection.getImageUrl());
  //    return userInfo;
  //  }
}
